home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 22 / Amiga Format AFCD22 (Jan 1998, Issue 106).iso / -in_the_mag- / converters / graphics / netpbm / hpcdtoppm.0.6 / src / postscr.c < prev    next >
C/C++ Source or Header  |  1997-11-16  |  10KB  |  406 lines

  1. /* hpcdtoppm (Hadmut's pcdtoppm) v0.6
  2. *  Copyright (c) 1992, 1993, 1994 by Hadmut Danisch (danisch@ira.uka.de).
  3. *  Permission to use and distribute this software and its
  4. *  documentation for noncommercial use and without fee is hereby granted,
  5. *  provided that the above copyright notice appear in all copies and that
  6. *  both that copyright notice and this permission notice appear in
  7. *  supporting documentation. It is not allowed to sell this software in 
  8. *  any way. This software is not public domain.
  9. */
  10.  
  11. #include "hpcdtoppm.h"
  12. #define DITH_NEUTR 128
  13.  
  14. FLTPT PAPER_LEFT    =DEF_PAPER_LEFT;
  15. FLTPT PAPER_BOTTOM  =DEF_PAPER_BOTTOM;
  16. FLTPT PAPER_WIDTH   =DEF_PAPER_WIDTH;
  17. FLTPT PAPER_HEIGHT  =DEF_PAPER_HEIGHT;
  18. FLTPT PRINTER_XDPI  =DEF_DPI;
  19. FLTPT PRINTER_YDPI  =DEF_DPI;
  20. FLTPT PRINTER_FAK   =1.0;
  21. sINT  PSIZE_SET=0,DPI_SET=0,FAK_SET=0;
  22.  
  23.  
  24. static char pshdr[]="%%Creator: hpcdtoppm v0.6\n";
  25. static char hex[]="0123456789ABCDEF";
  26. #define HEX(x) {fputc(hex[((x)>>4)&0xf],fout);fputc(hex[(x)&0xf],fout);}
  27.  
  28.  
  29. /* find an appropriate scaling coefficient and generate a ps header
  30.  * including a BoundingBox comment and a translate/scale sequence to 
  31.  * fit the pixw*pixh image into a square on paper with PS user coordinates 
  32.  * x,y,w,h 
  33.  */
  34. static void size_dependant(FILE *fout,sINT pixw,sINT pixh,
  35.                            FLTPT x,FLTPT y,FLTPT w,FLTPT h)
  36. { FLTPT scale=(FLTPT)w/pixw,scaley=(FLTPT)h/pixh;
  37.  
  38.   if(scale>scaley) scale=scaley;
  39.   x+=w/2.0;y+=h/2.0;
  40.   fprintf(fout,"%%%%BoundingBox: %.8g %.8g %.8g %.8g\n",
  41.      x-scale*pixw/2.0,y-scale*pixh/2.0,
  42.      x+scale*pixw/2.0,y+scale*pixh/2.0);
  43.   fprintf(fout,"%s",pshdr);
  44.   fputs("%%Pages: 1 1\n",fout);
  45.  
  46.   if(pcdname) fprintf(fout,"%%%%Title: %s\n",pcdname);
  47.   fputs("%%EndComments\n\n",fout);
  48.  
  49.   fprintf(fout,"%f %f translate\n",x-scale*pixw/2.0,y-scale*pixh/2.0);
  50.   fprintf(fout,"%f %f scale\n",scale*pixw,scale*pixh);
  51. }
  52.  
  53.  
  54.  
  55. static void end_postscript(FILE *fout)
  56.  {
  57.   fputs("%%EOF\n\n",fout);
  58.  }
  59.  
  60.  
  61.  
  62.  
  63. static void sub_psgrey(FILE *fout,dim w,dim h, uBYTE *ptr,sdim zeil,sdim pix)
  64. { dim x,y;
  65.   register uBYTE *p;
  66.   sINT c;
  67.  
  68.   size_dependant(fout,w,h,PAPER_LEFT,PAPER_BOTTOM,PAPER_WIDTH,PAPER_HEIGHT);
  69.   fprintf(fout,"%d string\n",w);
  70.   fprintf(fout,"%d %d 8\n",w,h);    /* always 8 bit per channel */
  71.   fprintf(fout,"[%d 0 0 %d 0 %d]\n",w,-h,h);
  72.   fputs("{currentfile 1 index readhexstring pop} image\n",fout);
  73.   
  74.   c=0;
  75.   for(y=0;y<h;y++,ptr+=zeil)
  76.     for(p=ptr,x=0;x<w;x++,p+=pix)
  77.       {HEX(*p);
  78.        if(!(++c % 36)) fputs("\n",fout);
  79.       }
  80.  
  81.   fputs("\npop\n\n",fout);
  82. }
  83.  
  84.  
  85.  
  86.  
  87.  
  88.  
  89.  
  90. void write_epsgrey(FILE *fout,dim w,dim h, uBYTE *ptr,sdim zeil,sdim pix)
  91.   fputs("%!PS-Adobe-2.0 EPSF-2.0\n",fout);
  92.   sub_psgrey(fout,w,h, ptr,zeil,pix);
  93.   end_postscript(fout);
  94. }
  95.  
  96. void write_psgrey(FILE *fout,dim w,dim h, uBYTE *ptr,sdim zeil,sdim pix)
  97.   fputs("%!PS-Adobe-2.0\n",fout);
  98.   sub_psgrey(fout,w,h, ptr,zeil,pix);
  99.   fputs("showpage\n",fout);
  100.   end_postscript(fout);
  101. }
  102.  
  103.  
  104.  
  105.  
  106.  
  107.  
  108.  
  109.  
  110.  
  111.  
  112.  
  113. static void sub_psrgb(FILE *fout,dim w,dim h, 
  114.                       uBYTE *rptr,sdim rzeil,sdim rpix,  
  115.               uBYTE *gptr,sdim gzeil,sdim gpix,  
  116.               uBYTE *bptr,sdim bzeil,sdim bpix) 
  117. { dim x,y;
  118.   register uBYTE *pr,*pg,*pb;
  119.   sINT c;
  120.  
  121.   size_dependant(fout,w,h,PAPER_LEFT,PAPER_BOTTOM,PAPER_WIDTH,PAPER_HEIGHT);
  122.   fprintf(fout,"%d string\n",w*3);
  123.   fprintf(fout,"%d %d 8\n",w,h);    /* always 8 bit per channel */
  124.   fprintf(fout,"[%d 0 0 %d 0 %d]\n",w,-h,h);
  125.   fputs("{currentfile 1 index readhexstring pop} false 3 colorimage\n",fout);
  126.   
  127.   c=0; 
  128.   for(y=0;y<h;y++,rptr+=rzeil,gptr+=gzeil,bptr+=bzeil)
  129.     for(pr=rptr,pg=gptr,pb=bptr,x=0;x<w;x++,pr+=rpix,pg+=gpix,pb+=bpix)
  130.       {HEX(*pr);HEX(*pg);HEX(*pb);
  131.        if(!(++c % 12)) fputs("\n",fout);
  132.       }
  133.  
  134.   fputs("\npop\n\n",fout);
  135. }
  136.  
  137.  
  138. void write_epsrgb(FILE *fout,dim w,dim h, 
  139.                       uBYTE *rptr,sdim rzeil,sdim rpix,  
  140.               uBYTE *gptr,sdim gzeil,sdim gpix,  
  141.               uBYTE *bptr,sdim bzeil,sdim bpix) 
  142.   fputs("%!PS-Adobe-2.0 EPSF-2.0\n",fout);
  143.   sub_psrgb(fout,w,h, rptr,rzeil,rpix,gptr,gzeil,gpix,bptr,bzeil,bpix);
  144.   end_postscript(fout);
  145. }
  146.  
  147.  
  148.  
  149. void write_psrgb(FILE *fout,dim w,dim h, 
  150.                       uBYTE *rptr,sdim rzeil,sdim rpix,  
  151.               uBYTE *gptr,sdim gzeil,sdim gpix,  
  152.               uBYTE *bptr,sdim bzeil,sdim bpix) 
  153.   fputs("%!PS-Adobe-2.0\n",fout);
  154.   sub_psrgb(fout,w,h, rptr,rzeil,rpix,gptr,gzeil,gpix,bptr,bzeil,bpix);
  155.   fputs("showpage\n",fout);
  156.   end_postscript(fout);
  157. }
  158.  
  159.  
  160.  
  161.  
  162.  
  163.  
  164.  
  165.  
  166.  
  167. typedef sINT dt;
  168. extern sINT dithtab[];
  169. #define DS 4
  170. #define DA (1<<(DS-1))
  171. #define DT 127
  172.  
  173. static void fakcopy(dim worig,dim horig, uBYTE *ptr1,sdim zeil,sdim pix,
  174.                     sdim wx,sINT zn,dt *dest)
  175.  {FLTPT owf,ohf,wbruch,hbruch,m1,m2,ha,hb;
  176.   dim   owd,ohd,x;
  177.   uBYTE *ptr2;
  178.   sINT  md;
  179.   
  180.   ohf=zn/PRINTER_FAK;
  181.   ohd=(dim)ohf;
  182.   hbruch=ohf-(FLTPT)ohd;
  183.   if(ohd>=horig) error(E_INTERN);
  184.  
  185.   ptr1+=zeil*ohd;
  186.   ptr2= (ohd < horig - 1) ? ptr1+zeil : ptr1;
  187.  
  188.   dest[-1]=DITH_NEUTR;
  189.  
  190.   for(x=0;x<wx;x++)
  191.    {owf=x/PRINTER_FAK;
  192.     owd=(dim)owf;
  193.     wbruch=owf-(FLTPT)owd;
  194.     if(owd>=worig) error(E_INTERN);
  195.  
  196.     if(owd<worig-1)
  197.      {ha=(FLTPT)ptr1[owd*pix];
  198.       hb=(FLTPT)ptr1[(owd+1)*pix];
  199.       m1=ha+wbruch*(hb-ha);
  200.  
  201.       ha=(FLTPT)ptr2[owd*pix];
  202.       hb=(FLTPT)ptr2[(owd+1)*pix];
  203.       m2=ha+wbruch*(hb-ha);
  204.      }
  205.     else
  206.      { m1=(FLTPT)ptr1[owd*pix];
  207.        m2=(FLTPT)ptr2[owd*pix];
  208.      }
  209.     md=(sINT)(m1+hbruch*(m2-m1));
  210.     if(md<0 || md>255) {fprintf(stderr,"md %d\n",md); error(E_INTERN);}
  211.     *(dest++)=dithtab[md];
  212.  
  213.    }
  214.   
  215.   dest[0]=DITH_NEUTR;
  216.  }
  217.  
  218. static void sub_psdith(FILE *fout,dim worig,dim horig, uBYTE *ptr,sdim zeil,sdim pix)
  219. { register uBYTE *p;
  220.   sINT c,i,ii,j,reg,bit;
  221.   dt new,diff;
  222.   dt *dP1,*dP2,*akt,*nex,*help,*rrun;
  223.   dim ww=0,wl=0,wr=0,hh=0,ho=0,hu=0,wx=0,hx=0;
  224.   int ccase;
  225.   FLTPT PW=0.0,PH=0.0;
  226.  
  227. #define copy(n,d) {if(FAK_SET) fakcopy(worig,horig,ptr,zeil,pix,wx,n,d); \
  228.                    else{p=ptr+((n)*zeil); rrun=d;\
  229.                         for(ii=0;ii<wx;ii++,p+=pix,rrun++) *rrun = dithtab[*p]; \
  230.                         d[-1]=d[wx]=DITH_NEUTR; }}
  231.  
  232.  
  233. #define pr(x) { reg= (reg<<1) | x; bit++;    \
  234.      if(bit==8) {HEX(reg);   \
  235.                  if(!(++c % 36)) fputs("\n",fout);\
  236.                  bit=reg=0;}}
  237.  
  238. #define flush { while(bit) pr(1); }
  239. #define fill pr(1)
  240.  
  241.  
  242.  
  243. #define MakeFit(wi,he) {  ww=(wi+7) & (~7);   wl=(ww-wi)/2;  wr=ww-wi-wl; \
  244.                           hh=(he+7) & (~7);   ho=(hh-he)/2;  hu=hh-he-ho; }
  245.  
  246.  
  247.   
  248.   ccase=( FAK_SET   ? 4 : 0 ) |
  249.         ( DPI_SET   ? 2 : 0 ) |
  250.         ( PSIZE_SET ? 1 : 0 ) ;
  251.  
  252.  
  253.   switch (ccase)
  254.    {case 0: /*  no option or -dpi option */
  255.     case 2: hx=horig;
  256.             wx=worig;
  257.             MakeFit(wx,hx);
  258.             PW=ww*72.0/PRINTER_XDPI;
  259.             PH=hh*72.0/PRINTER_YDPI;
  260.             break;
  261.  
  262.     case 1: /* paper size set with -pw and/or -ph */
  263.             hx=horig;
  264.             wx=worig;
  265.             MakeFit(wx,hx);
  266.             PW=PAPER_WIDTH;
  267.             PH=PAPER_HEIGHT;
  268.             break;
  269.  
  270.     case 6: /* -fak option (and perhaps -dpi) */
  271.     case 4: hx=PRINTER_FAK*horig+0.5;
  272.             wx=PRINTER_FAK*worig+0.5;
  273.             MakeFit(wx,hx);
  274.             PW=ww*72.0/PRINTER_XDPI;
  275.             PH=hh*72.0/PRINTER_YDPI; 
  276.             break;
  277.  
  278.     case 5: /* -fak and papersize */
  279.             hx=PRINTER_FAK*horig+0.5;
  280.             wx=PRINTER_FAK*worig+0.5;
  281.             MakeFit(wx,hx);
  282.             PW=PAPER_WIDTH;
  283.             PH=PAPER_HEIGHT;
  284.             break;
  285.  
  286.     case 3: /* papersize and dpi set, probably the most important case */
  287.             PW=PAPER_WIDTH;
  288.             PH=PAPER_HEIGHT;
  289.  
  290.             FAK_SET=1;
  291.             {FLTPT fw,fh;
  292.              fw=PW/72.0*PRINTER_XDPI/worig;
  293.              fh=PH/72.0*PRINTER_YDPI/horig;
  294.              PRINTER_FAK=MIN(fw,fh);
  295.             }
  296.             hx=PRINTER_FAK*horig+0.5;
  297.             wx=PRINTER_FAK*worig+0.5;
  298.             MakeFit(wx,hx);
  299.             PW=ww*72.0/PRINTER_XDPI;
  300.             PH=hh*72.0/PRINTER_YDPI; 
  301.             break;
  302.  
  303.  
  304.     case 7: /* size, dpi and factor set, this case should have been
  305.                cought earlier... */
  306.     default: error(E_INTERN);
  307.    };
  308.  
  309.   if(FAK_SET && (PRINTER_FAK<=0.0  || PRINTER_FAK >=1000.0)) error(E_PRPAR);
  310.   if(PW<=0.0 || PH<=0.0) error(E_PRPAR);
  311.  
  312.   if(wx < 4 || hx < 4) error(E_PRPAR);
  313.  
  314.  
  315.   if (!(dP1=(dt *)malloc((wx+2)*sizeof(dt)))) error(E_MEM);
  316.   if (!(dP2=(dt *)malloc((wx+2)*sizeof(dt)))) error(E_MEM);
  317.  
  318.  
  319.  
  320.   size_dependant(fout,ww,hh,PAPER_LEFT,PAPER_BOTTOM,PW,PH);
  321.  
  322.   fprintf(fout,"%d string\n",ww);
  323.   fprintf(fout,"%d %d 1\n",ww,hh);    /* always 8 bit per channel */
  324.   fprintf(fout,"[%d 0 0 %d 0 %d]\n",ww,-hh,hh);
  325.   fputs("{currentfile 1 index readhexstring pop} image\n",fout);
  326.   
  327.   c=bit=reg=0;
  328.   akt=dP1+1;
  329.   nex=dP2+1;
  330.  
  331.   for(i=0;i<ho;i++)
  332.     for(j=0;j<ww;j++)
  333.       fill;
  334.  
  335.   copy(0,nex);
  336.   for(i=0;i<hx;i++)
  337.    {help=akt; akt=nex; nex=help;
  338.     if(i<hx-1) copy(i+1,nex);
  339.  
  340.     if(i&1)
  341.       for(j=0;j<wx;j++)
  342.        { new=akt[j]>DT ? 255 : 0;
  343.          diff = akt[j]-new;
  344.          akt[j]=new;
  345.          akt[j+1]+=(diff*7 + DA)>>DS;
  346.          nex[j+1]+=(diff   + DA)>>DS;
  347.          nex[j  ]+=(diff*5 + DA)>>DS;
  348.          nex[j-1]+=(diff*3 + DA)>>DS;
  349.        }
  350.     else
  351.       for(j=wx-1;j>=0;j--)
  352.        { new=akt[j]>DT ? 255 : 0;
  353.          diff = akt[j]-new;
  354.          akt[j]=new;
  355.          akt[j-1]+=(diff*7 + DA)>>DS;
  356.          nex[j-1]+=(diff   + DA)>>DS;
  357.          nex[j  ]+=(diff*5 + DA)>>DS;
  358.          nex[j+1]+=(diff*3 + DA)>>DS;
  359.        }
  360.  
  361.  
  362.     for(j=0;j<wl;j++) fill;
  363.  
  364.     for(j=0;j<wx;j++)
  365.      {if (akt[j]>DT) { pr(1); }
  366.       else           { pr(0); }
  367.      }
  368.  
  369.     for(j=0;j<wr;j++) fill;
  370.  
  371.     flush;
  372.    }
  373.  
  374.   for(i=0;i<hu;i++)
  375.     for(j=0;j<ww;j++)
  376.       fill;
  377.   flush;
  378.  
  379.   fputs("\npop\n\n",fout);
  380.   free(dP1);
  381.   free(dP2);
  382. }
  383.  
  384.  
  385. void write_epsdith(FILE *fout,dim w,dim h, uBYTE *ptr,sdim zeil,sdim pix)
  386.   fputs("%!PS-Adobe-2.0 EPSF-2.0\n",fout);
  387.   sub_psdith(fout,w,h, ptr,zeil,pix);
  388.   end_postscript(fout);
  389. }
  390.  
  391. void write_psdith(FILE *fout,dim w,dim h, uBYTE *ptr,sdim zeil,sdim pix)
  392.   fputs("%!PS-Adobe-2.0\n",fout);
  393.   sub_psdith(fout,w,h, ptr,zeil,pix);
  394.   fputs("showpage\n",fout);
  395.   end_postscript(fout);
  396. }
  397.  
  398.  
  399.  
  400.